package proj2501.geo_util;

/** Represents a directed line segment.*/
public class LineSegmentD2 {
	private VectorD2 v1;
	public VectorD2 getV1() { return v1; }
	
	private VectorD2 v2;
	public VectorD2 getV2() { return v2; }

	private VectorD2 v1ToV2;
	public VectorD2 getV1ToV2() {
		if (v1ToV2 == null) {
			v1ToV2 = v2.sub(v1);
		}
		return v1ToV2;
	}
	
	public LineSegmentD2(VectorD2 v1, VectorD2 v2) {
		construct(v1, v2);
	}
	
	public LineSegmentD2(double x1, double y1, double x2, double y2) {
		VectorD2 v1 = new VectorD2(x1, y1);
		VectorD2 v2 = new VectorD2(x2, y2);
		construct(v1, v2);
	}
	
	private void construct(VectorD2 p1, VectorD2 p2) {
		this.v1 = p1;
		this.v2 = p2;
	}
	
	@Override
	public String toString() {
		return "(" + v1 + ", " + v2 + ")";
	}
	
	public double getLength() {
		return getV1ToV2().getLength();
	}
	
	public boolean isIntersected(LineSegmentD2 line) {
		double line2p1isLeft = getV1ToV2().cross(line.v1.sub(v1));
		double line2p2isLeft = getV1ToV2().cross(line.v2.sub(v1));
		double line1p1isLeft = line.getV1ToV2().cross(v1.sub(line.v1));
		double line1p2isLeft = line.getV1ToV2().cross(v2.sub(line.v1));
		return line2p1isLeft * line2p2isLeft <= 0 && line1p1isLeft * line1p2isLeft <= 0;
	}
	
	public VectorD2 getIntersection(LineSegmentD2 line) {
		if (! isIntersected(line)) {
			return null;
		}
		double front = Math.abs(line.getV1ToV2().cross(v1.sub(line.v1)));
		double back = Math.abs(line.getV1ToV2().cross(v2.sub(line.v1)));
		double ratio = front / (front + back);
		return v1.add(getV1ToV2().mul(ratio));
	}
}
